package cz.acies.genea.data.dao;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;

import cz.acies.data.DBConnector;
import cz.acies.data.dao.DefaultDAO;
import cz.acies.data.dao.DefaultMapListHandler;
import cz.acies.data.dao.DefaultRowProcessor;
import cz.acies.data.persist.ModelObject;
import cz.acies.genea.data.persist.GedFamily;
import cz.acies.genea.data.persist.GedPerson;
import cz.acies.genea.data.persist.GedPersonBinding;
import cz.acies.uniql.sql.InsertQuery;
import cz.acies.uniql.sql.SelectQuery;
import cz.acies.uniql.sql.UpdateQuery;
import cz.acies.uniql.sql.element.UniQLCondition;
import cz.acies.uniql.sql.element.UniQLWhere;
import cz.acies.utils.UIDGenerator;

public class GedPersonBindingDAO extends DefaultDAO
{
	public GedPersonBindingDAO() {
		this.tableName = "person_bindings";
	}
	
	public GedPersonBinding selectById(String id) {
		GedPersonBinding record = null;
		try {
			//super.selectById(id, id, c)
			QueryRunner qr = new QueryRunner(DBConnector.instance().getDataSource());
			List<Map<String, Object>> list = qr.query(new SelectQuery(dbmd())
				.addFrom(""+tableName)
				.add(new UniQLCondition(tableName+".id", "=", "'"+id+"'"))
				.toSQLString(), new DefaultMapListHandler(new DefaultRowProcessor()));
			for (Map<String, Object> param : list) {
				record = new GedPersonBinding(id, param);
			}
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return record;
	}

	public String insert(GedPersonBinding record) {
		String id = record.getId();
		try {
			if (id == null || id.trim().length() == 0 || !id.startsWith("GE.B.")) {
				id = UIDGenerator.createUID("GE.B");
			}
			InsertQuery sql = new InsertQuery(dbmd()).into(""+tableName)
				.addParam("id", ""+id)
				.addParam("objectId", ""+(record.hasObjectId() ? record.getObjectId() : ""))
				.addParam("connectId", ""+((record.hasConnectId()) ? record.getConnectId() : ""))				
				.addParam("bindingType", ""+((record.hasBindingType()) ? record.getBindingType() : "UNKNOW"))
				.addParam("extend", ""+((record.hasExtend()) ? record.getExtend() : ""));
			
			QueryRunner qr = new QueryRunner(DBConnector.instance().getDataSource());
			qr.update(sql.toSQLString());
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return id;
	}

	public void update(GedPersonBinding record) {
		if (record != null) {
			try {
				UpdateQuery sql = new UpdateQuery(dbmd())
					.addFrom("person")
					.addParam("objectId", ""+(record.hasObjectId() ? record.getObjectId() : ""))
					.addParam("connectId", ""+((record.hasConnectId()) ? record.getConnectId() : ""))				
					.addParam("bindingType", ""+((record.hasBindingType()) ? record.getBindingType() : "UNKNOW"))
					.addParam("extend", ""+((record.hasExtend()) ? record.getExtend() : ""))
					.add(new UniQLCondition("id", "=", "'"+record.getId()+"'"));

				QueryRunner qr = new QueryRunner(DBConnector.instance().getDataSource());
				qr.update(sql.toSQLString());
			} catch (Exception exc) {
				exc.printStackTrace();
			}
		}
	}

	public void update(Map<String, Object> params) throws Exception {
		GedPersonBinding record = new GedPersonBinding();
		for (String key : params.keySet()) {
			if (key.equals("id")) record.setId((String)params.get(key));
			if (key.equals("objectId")) record.setObjectId((String)params.get(key));
			if (key.equals("connectId")) record.setConnectId((String)params.get(key));
			if (key.equals("bindingType")) record.setBindingType((String)params.get(key));
		}
		String id = record.getId();
		/*
		String objectId = (record.hasObjectId() ? record.getObjectId() : ""))
		String connectId = ((record.hasConnectId()) ? record.getConnectId() : ""))				
		String bindingType = ((record.hasBindingType()) ? record.getBindingType() : "UNKNOW");
		*/
		if (existsRecord(id)) {
			this.update(record);
		} else {
			this.insert(record);
		}
	}

	// -----  -----------------------------------------------------------------

	public boolean existsRecord(GedPersonBinding bind) throws Exception {
		if (bind == null) return false;
		if (!bind.hasId()) {
			if (!bind.hasObjectId() || !bind.hasConnectId()) return false;
			UniQLWhere where = new UniQLWhere()
				.add(new UniQLCondition("objectId", "=", "'"+bind.getObjectId()+"'"))
				.add(new UniQLCondition("connectId", "=", "'"+bind.getConnectId()+"'"))
				.add(new UniQLCondition("bindingType", "=", "'"+bind.getBindingType()+"'"));
			return super.existsRecord(where);	
		} else {
			if (existsRecord(bind.getId())) {
				return true;
			} else {
				UniQLWhere where = new UniQLWhere()
					.add(new UniQLCondition("objectId", "=", "'"+bind.getObjectId()+"'"))
					.add(new UniQLCondition("connectId", "=", "'"+bind.getConnectId()+"'"))
					.add(new UniQLCondition("bindingType", "=", "'"+bind.getBindingType()+"'"));
				return super.existsRecord(where);				
			}
		}
	}

	public boolean existsRecord(String objectId, String connectId, String bindingType) throws Exception {
		UniQLWhere where = new UniQLWhere()
			.add(new UniQLCondition("objectId", "=", "'"+objectId+"'"))
			.add(new UniQLCondition("connectId", "=", "'"+connectId+"'"))
			.add(new UniQLCondition("bindingType", "=", "'"+bindingType+"'"));
		return super.existsRecord(where);	
	}

	public boolean existsRecord(String objectId, String connectId, String bindingType, String extend) throws Exception {
		UniQLWhere where = new UniQLWhere()
			.add(new UniQLCondition("objectId", "=", "'"+objectId+"'"))
			.add(new UniQLCondition("connectId", "=", "'"+connectId+"'"))
			.add(new UniQLCondition("bindingType", "=", "'"+bindingType+"'"))
			.add(new UniQLCondition("extend", "=", "'"+extend+"'"));
		return super.existsRecord(where);	
	}

	// -----  -----------------------------------------------------------------
	
	public List<GedPersonBinding> selectAllByFamily(GedFamily family) throws Exception {
		List<GedPersonBinding> data = new LinkedList<GedPersonBinding>();
		UniQLWhere where = new UniQLWhere()
		.add(new UniQLCondition(tableName+".objectID", "=", "'"+family.getId()+"'"));
		List<ModelObject> list = super.selectByWhere(this.tableName, where, GedPersonBinding.class);
		for (ModelObject obj : list) {
			if (obj instanceof GedPersonBinding) data.add((GedPersonBinding) obj);
		}
		return data;
	}

	public List<GedPersonBinding> selectAllByPerson(GedPerson person) throws Exception {
		List<GedPersonBinding> data = new LinkedList<GedPersonBinding>();
		UniQLWhere where = new UniQLWhere()
		.add(new UniQLCondition(tableName+".objectID", "=", "'"+person.getId()+"'"));
		List<ModelObject> list = super.selectByWhere(this.tableName, where, GedPersonBinding.class);
		for (ModelObject obj : list) {
			if (obj instanceof GedPersonBinding) data.add((GedPersonBinding) obj);
		}
		return data;
	}

}
